import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import { DeepSeekChatCompletionRequestDto } from '../dto/deepseek/chat-completion-request.dto';
import { ChatCompletionResponseDto } from '../dto/completion-response.dto';
import { JsonFormatterResponseDto } from '../dto/json-formatter-request.dto';
import {
  SocialMediaPostOptions,
  SocialMediaPostResult,
} from '../dto/deepseek/social-media-types';

@Injectable()
export class DeepSeekService {
  private readonly logger = new Logger(DeepSeekService.name);
  private readonly apiKey: string;
  private readonly apiBaseUrl: string;

  constructor(
    private readonly httpService: HttpService,
    private readonly configService: ConfigService,
  ) {
    this.apiKey =
      this.configService.get<string>('ai.deepseek.apiKey', '') ||
      process.env.DEEPSEEK_API_KEY ||
      '';
    this.apiBaseUrl =
      this.configService.get<string>('ai.deepseek.apiUrl', '') ||
      process.env.DEEPSEEK_API_URL ||
      'https://api.deepseek.com/v1';

    if (!this.apiKey) {
      this.logger.warn(
        'DeepSeek API key not found. Please set DEEPSEEK_API_KEY in your environment variables.',
      );
    }
  }

  /**
   * 获取用户余额
   * @returns 余额信息
   */
  async getUserBalance() {
    const response = await firstValueFrom(
      this.httpService.get('https://api.deepseek.com/user/balance', {
        headers: {
          Authorization: `Bearer ${this.apiKey}`,
        },
      }),
    );
    return response.data;
  }

  /**
   * 获取 DeepSeek 可用模型列表
   * @returns 模型列表信息
   */
  async getModels() {
    try {
      if (!this.apiKey) {
        throw new Error('DeepSeek API key is not set');
      }

      const response = await firstValueFrom(
        this.httpService.get('https://api.deepseek.com/models', {
          headers: {
            Accept: 'application/json',
            Authorization: `Bearer ${this.apiKey}`,
          },
        }),
      );

      return response.data;
    } catch (error) {
      this.logger.error(
        `Error fetching DeepSeek models: ${
          error instanceof Error ? error.message : String(error)
        }`,
        error instanceof Error ? error.stack : undefined,
      );

      // 确保返回的是 Error 类型
      if (error instanceof Error) {
        throw error;
      }
      throw new Error(`DeepSeek API error: ${String(error)}`);
    }
  }

  /**
   * 生成聊天完成
   * @param request 聊天完成请求
   * @returns 聊天完成响应
   */
  async generateChatCompletion(
    request: DeepSeekChatCompletionRequestDto,
  ): Promise<ChatCompletionResponseDto> {
    try {
      this.logger.log(
        `Sending request to DeepSeek: ${JSON.stringify(request)}`,
      );

      const headers = {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${this.apiKey}`,
        'HTTP-Referer': 'https://ai-tools-api',
        'X-Title': 'AI-Tools API',
      };

      const response = await firstValueFrom(
        this.httpService.post(`${this.apiBaseUrl}/chat/completions`, request, {
          headers,
        }),
      );

      return {
        model: response.data.model,
        message: response.data.choices[0].message,
        rawResponse: response.data,
      };
    } catch (error) {
      this.logger.error(
        `Error calling DeepSeek API: ${error.message}`,
        error.stack,
      );
      throw error;
    }
  }

  /**
   * 将文本内容转换为结构化的 JSON 格式
   * @param textContent 要格式化的文本内容
   * @param model 模型名称
   * @param maxTokens 最大生成令牌数
   * @returns 格式化后的 JSON 数据
   */
  async formatToJson(
    textContent: string,
    model: string = 'deepseek-chat',
    maxTokens: number = 2048,
  ): Promise<JsonFormatterResponseDto> {
    try {
      if (!this.apiKey) {
        throw new Error('DeepSeek API key is not set');
      }

      // 构建提示词
      const promptText = `# 角色: 内容JSON格式化专家
根据用户提供的需要处理的文本内容，将其转换为结构化的JSON格式。
请遵循以下要求：
1. 分析内容的主题和关键信息
2. 设计合理的JSON结构，包含所有重要信息
3. 确保生成的JSON格式有效且可解析
4. 不要添加任何原文中不存在的信息
5. 直接返回JSON对象，不要有任何前缀或后缀说明

以下是需要处理的文本内容：
${textContent}`;

      // 使用generateChatCompletion
      const response = await this.generateChatCompletion({
        model: model,
        messages: [{ role: 'user', content: promptText }],
        max_tokens: maxTokens,
        temperature: 0.3,
      });

      // 解析响应
      const content = response.message.content || '';

      // 返回格式化后的结果，确保符合JsonFormatterResponseDto结构
      return {
        result: content,
        rawResponse: response.rawResponse,
      };
    } catch (error) {
      this.logger.error(
        `Error formatting to JSON: ${
          error instanceof Error ? error.message : String(error)
        }`,
        error instanceof Error ? error.stack : undefined,
      );

      // 重新抛出错误，但确保它是 Error 类型
      if (error instanceof Error) {
        throw error;
      }
      throw new Error(`DeepSeek API error: ${String(error)}`);
    }
  }

  /**
   * 生成小红书/小绿书爆款图文笔记
   * @param template 内容模板
   * @param keywords 关键词列表
   * @param imagePrompt 图片生成提示词
   * @param options 配置选项
   * @returns 生成的图文笔记内容
   */
  async generateSocialMediaPost(
    template: string,
    keywords: string[],
    imagePrompt: string,
    options: SocialMediaPostOptions = {},
  ): Promise<{ content: string; rawResponse: any }> {
    const {
      platform = 'xiaohongshu',
      includeHashtags = true,
      postLength = 'medium',
      style = 'trendy',
      imageCount = 1,
    } = options;

    // 构建提示词系统消息
    const systemPrompt = `你是一位专业的${platform === 'xiaohongshu' ? '小红书' : '小绿书'}爆款内容创作专家。
请根据用户提供的关键词和模板，创建一篇吸引人的${platform === 'xiaohongshu' ? '小红书' : '小绿书'}图文笔记。
内容长度: ${postLength === 'short' ? '300-500字' : postLength === 'medium' ? '500-800字' : '800-1200字'}
风格: ${style === 'casual' ? '轻松随意' : style === 'professional' ? '专业权威' : '潮流时尚'}
${includeHashtags ? '包含5-8个相关话题标签' : '不需要包含话题标签'}
需要生成${imageCount}张图片的详细描述（作为DALL-E或Midjourney的提示词）。
请按照以下格式输出:

标题: [引人注目的标题]

正文:
[分段的正文内容]

${includeHashtags ? '话题标签:\n[相关话题标签，以#开头]' : ''}

图片描述:
[图片1的详细描述，要能作为AI绘图的提示词]
${imageCount > 1 ? '[图片2的详细描述]' : ''}
${imageCount > 2 ? '[图片3的详细描述]' : ''}`;

    // 构建用户提示消息
    const userPrompt = `请根据以下模板和关键词创建一篇${platform === 'xiaohongshu' ? '小红书' : '小绿书'}爆款笔记：
    
模板: ${template}
    
关键词: ${keywords.join(', ')}
    
图片主题: ${imagePrompt}`;

    // 构建API请求
    const request: DeepSeekChatCompletionRequestDto = {
      model: 'deepseek-chat',
      messages: [
        {
          role: 'system',
          content: systemPrompt,
        },
        {
          role: 'user',
          content: userPrompt,
        },
      ],
      temperature: 0.7,
      max_tokens: 2000,
    };

    // 调用API生成内容
    const response = await this.generateChatCompletion(request);

    return {
      content: response.message.content,
      rawResponse: response.rawResponse,
    };
  }

  /**
   * 批量生成小红书/小绿书爆款图文笔记
   * @param templates 内容模板列表
   * @param keywordSets 关键词集合列表
   * @param imagePrompts 图片生成提示词列表
   * @param options 配置选项
   * @returns 生成的图文笔记内容列表
   */
  async batchGenerateSocialMediaPosts(
    templates: string[],
    keywordSets: string[][],
    imagePrompts: string[],
    options: {
      platform?: 'xiaohongshu' | 'xiaolvshu';
      includeHashtags?: boolean;
      postLength?: 'short' | 'medium' | 'long';
      style?: 'casual' | 'professional' | 'trendy';
      imageCount?: number;
    } = {},
  ): Promise<SocialMediaPostResult[]> {
    const results: SocialMediaPostResult[] = [];
    const totalCount = Math.min(
      templates.length,
      keywordSets.length,
      imagePrompts.length,
    );

    for (let i = 0; i < totalCount; i++) {
      const template = templates[i % templates.length];
      const keywords = keywordSets[i % keywordSets.length];
      const imagePrompt = imagePrompts[i % imagePrompts.length];

      try {
        const result = await this.generateSocialMediaPost(
          template,
          keywords,
          imagePrompt,
          options,
        );

        results.push({
          index: i,
          template,
          keywords,
          imagePrompt,
          content: result.content,
          status: 'success',
        });
      } catch (error) {
        this.logger.error(
          `Error generating social media post #${i}: ${error.message}`,
          error.stack,
        );

        results.push({
          index: i,
          template,
          keywords,
          imagePrompt,
          error: error.message,
          status: 'error',
        });
      }
    }

    return results;
  }
}
